home *** CD-ROM | disk | FTP | other *** search
/ Delphi Magazine Collection 2001 / Delphi Magazine Collection 20001 (2001).iso / DISKS / Issue40 / COMCorn / ViewObj.pas < prev   
Encoding:
Pascal/Delphi Source File  |  1998-11-11  |  8.3 KB  |  268 lines

  1. unit ViewObj;
  2.  
  3. interface
  4. uses Windows, ActiveX, ComObj, ShlObj, CommCtrl, Main, UtilObjs, ExtForm;
  5.  
  6. type
  7.   // IShellView implementation for namespace extension.  Note that this must be
  8.   // a separate, stand-alone class because multiple IShellViews can be requested
  9.   // from a single IShellFolder.
  10.   TViewObject = class(TMultiAggregatedObject, IShellView)
  11.   private
  12.     FControlExt: TComNameExt;
  13.     FOwner: HWND;
  14.     FShellBrowser: IShellBrowser;
  15.     FViewForm: TMainForm;
  16.     FFolderSettings: TFolderSettings;
  17.   protected
  18.     { IOleWindow methods }
  19.     function GetWindow(out wnd: HWND): HResult; stdcall;
  20.     function ContextSensitiveHelp(fEnterMode: BOOL): HResult; stdcall;
  21.     { IShellView methods }
  22.     function TranslateAccelerator(var Msg: TMsg): HResult; stdcall;
  23.     function EnableModeless(Enable: Boolean): HResult; stdcall;
  24.     function UIActivate(State: UINT): HResult; stdcall;
  25.     function Refresh: HResult; stdcall;
  26.     function CreateViewWindow(PrevView: IShellView;
  27.       var FolderSettings: TFolderSettings; ShellBrowser: IShellBrowser;
  28.       var Rect: TRect; out Wnd: HWND): HResult; stdcall;
  29.     function DestroyViewWindow: HResult; stdcall;
  30.     function GetCurrentInfo(out FolderSettings: TFolderSettings): HResult; stdcall;
  31.     function AddPropertySheetPages(Reseved: DWORD;
  32.       lpfnAddPage: TFNAddPropSheetPage; lParam: LPARAM): HResult; stdcall;
  33.     function SaveViewState: HResult; stdcall;
  34.     function SelectItem(pidl: PItemIDList; flags: UINT): HResult; stdcall;
  35.     function GetItemObject(Item: UINT; const iid: TIID; IPtr: Pointer): HResult; stdcall;
  36.   public
  37.     constructor Create(Controller: TComNameExt; Owner: HWND); reintroduce;
  38.     procedure ContextMenu;
  39.     property ControlExt: TComNameExt read FControlExt;
  40.   end;
  41.  
  42. implementation
  43.  
  44. uses SysUtils, ComCtrls, ShellAPI, Graphics, Menus, Controls;
  45.  
  46. { TViewObject }
  47.  
  48. constructor TViewObject.Create(Controller: TComNameExt; Owner: HWND);
  49. begin
  50.   inherited Create(Controller);
  51.   FControlExt := Controller;
  52.   FOwner := Owner;
  53. end;
  54.  
  55. { TViewObject.IOleWindow }
  56.  
  57. function TViewObject.GetWindow(out wnd: HWnd): HResult;
  58. begin
  59.   Result := E_NOTIMPL;
  60. end;
  61.  
  62. function TViewObject.ContextSensitiveHelp(fEnterMode: BOOL): HResult;
  63. begin
  64.   Result := E_NOTIMPL;
  65. end;
  66.  
  67. { TViewObject.IShellView }
  68.  
  69. function TViewObject.TranslateAccelerator(var Msg: TMsg): HResult;
  70. begin
  71.   Result := S_FALSE;
  72. end;
  73.  
  74. function TViewObject.EnableModeless(Enable: Boolean): HResult;
  75. begin
  76.   Result := E_NOTIMPL;
  77. end;
  78.  
  79. function TViewObject.UIActivate(State: UINT): HResult;
  80. begin
  81.   // !!
  82.   Result := S_OK;
  83. end;
  84.  
  85. function TViewObject.Refresh: HResult;
  86. var
  87.   EnumObj: IEnumIDList;
  88.   Folder: IShellFolder;
  89.   IconOMatic: IExtractIcon;
  90.   Fetched: ULONG;
  91.   ItemID: array[1..100] of PItemIDList;
  92.   Str: TStrRet;
  93.   ListItem: TListItem;
  94.   I, IconIndex: Integer;
  95.   IconIdx: Word;
  96.   IconFile: array[0..MAX_PATH] of char;
  97.   Icon: HICON;
  98. begin
  99.   Result := S_OK;
  100.   try
  101.     // Get latest info from registry
  102.     FControlExt.RefreshServerList;
  103.     // Clear UI and any previously allocated pidls
  104.     FViewForm.ListView.Items.BeginUpdate;
  105.     try
  106.       with FViewForm.ListView do
  107.       begin
  108.         for I := 0 to Items.Count - 1 do
  109.           if Items[I].Data <> nil then
  110.             FControlExt.ShellMalloc.Free(Items[I].Data);
  111.         Items.Clear;
  112.       end;
  113.       FViewForm.ImageList.Clear;
  114.       // Get IEnumIDList interface from my shell folder
  115.       Folder := FControlExt as IShellFolder;
  116.       Folder.EnumObjects(FOwner, SHCONTF_FOLDERS or SHCONTF_NONFOLDERS or
  117.         SHCONTF_INCLUDEHIDDEN, EnumObj);
  118.       // Enumerate all objects in my namespace, fetching 100 at a time
  119.       // in order to speed things up a little.
  120.       while EnumObj.Next(100, ItemID[1], Fetched) = S_OK do
  121.         for I := 1 to Fetched do
  122.         begin
  123.           // Add a new item to my listview
  124.           ListItem := FViewForm.ListView.Items.Add;
  125.           ListItem.Data := ItemID[I];
  126.           // Get the display name for the pidl
  127.           OleCheck(Folder.GetDisplayNameOf(ItemID[I], 0, Str));
  128.           case Str.uType of
  129.             STRRET_WSTR:
  130.               begin
  131.                 ListItem.Caption := WideCharToString(Str.pOleStr);
  132.                 FControlExt.ShellMalloc.Free(Str.pOleStr);
  133.               end;
  134.             STRRET_CSTR: ListItem.Caption := Str.cStr;
  135.           end;
  136.           // Get the IExtractIcon UI object for this pidl
  137.           if Folder.GetUIObjectOf(FOwner, 1, ItemID[I], IExtractIcon, nil,
  138.             Pointer(IconOMatic)) = S_OK then
  139.           begin
  140.             IconOMatic.GetIconLocation(GIL_FORSHELL, IconFile, SizeOf(IconFile),
  141.               IconIndex, Fetched);
  142.             if Fetched and GIL_NOTFILENAME = 0 then
  143.             begin
  144.               // Get Icon file, and add it to imagelist
  145.               IconIdx := IconIndex;
  146.               Icon := ExtractAssociatedIcon(MainInstance, IconFile, IconIdx);
  147.               if Icon <> 0 then
  148.                 ListItem.ImageIndex := ImageList_AddIcon(FViewForm.ImageList.Handle,
  149.                   Icon);
  150.             end;
  151.           end;
  152.         end;
  153.     finally
  154.       FViewForm.ListView.Items.EndUpdate;
  155.     end;
  156.   except
  157.     on E: TObject do
  158.       Result := Controller.SafeCallException(E, ExceptAddr);
  159.   end;
  160. end;
  161.  
  162. function TViewObject.CreateViewWindow(PrevView: IShellView;
  163.   var FolderSettings: TFolderSettings; ShellBrowser: IShellBrowser;
  164.   var Rect: TRect; out Wnd: HWND): HResult;
  165. var
  166.   MainWindow: HWND;
  167. begin
  168.   Result := S_OK;
  169.   try
  170.     FFolderSettings := FolderSettings;    // Save away folder settings
  171.     FShellBrowser := ShellBrowser;        // Save away shell's IShellBrowser
  172.     FShellBrowser.GetWindow(MainWindow);  // Get parent window for my window
  173.     FViewForm := TMainForm.Create(nil);   // Create my browser window
  174.     FViewForm.ShellView := Self;
  175.     FViewForm.ParentWindow := MainWindow; // Set parent and bounds
  176.     FViewForm.BoundsRect := Rect;
  177.     Refresh;                              // Rebuild list view
  178.     FViewForm.Show;                       // Show my window
  179.     Wnd := FViewForm.Handle;              // Return my window's handle
  180.   except
  181.     on E: TObject do
  182.       Result := Controller.SafeCallException(E, ExceptAddr);
  183.   end;
  184. end;
  185.  
  186. function TViewObject.DestroyViewWindow: HResult;
  187. begin
  188.   Result := S_OK;
  189.   try
  190.     FViewForm.Release;
  191.     FViewForm := nil;
  192.   except
  193.     on E: TObject do
  194.       Result := Controller.SafeCallException(E, ExceptAddr);
  195.   end;
  196. end;
  197.  
  198. function TViewObject.GetCurrentInfo(out FolderSettings: TFolderSettings): HResult;
  199. begin
  200.   Result := S_OK;
  201.   FolderSettings := FFolderSettings;
  202. end;
  203.  
  204. function TViewObject.AddPropertySheetPages(Reseved: DWORD;
  205.   lpfnAddPage: TFNAddPropSheetPage; lParam: LPARAM): HResult;
  206. begin
  207.   Result := E_NOTIMPL;
  208. end;
  209.  
  210. function TViewObject.SaveViewState: HResult;
  211. begin
  212.   // !!
  213.   Result := S_OK;
  214. end;
  215.  
  216. function TViewObject.SelectItem(pidl: PItemIDList; flags: UINT): HResult;
  217. begin
  218.   Result := E_NOTIMPL;
  219. end;
  220.  
  221. function TViewObject.GetItemObject(Item: UINT; const iid: TIID; IPtr: Pointer): HResult;
  222. begin
  223.   Result := E_NOTIMPL;
  224. end;
  225.  
  226. const
  227.   CmdFirst = FCIDM_SHVIEWFIRST + $1000;
  228.   CmdLast = FCIDM_SHVIEWFIRST + $2000;
  229.  
  230. procedure TViewObject.ContextMenu;
  231. var
  232.   Popup: HMENU;
  233.   ContextMenu: IContextMenu;
  234.   Selected: TListItem;
  235.   pidl: PItemIDList;
  236.   Choice: Word;
  237.   CmdInfo: TCMInvokeCommandInfo;
  238. begin
  239.   Selected := FViewForm.ListView.Selected;
  240.   if Selected <> nil then
  241.   begin
  242.     pidl := Selected.Data;
  243.     if (pidl <> nil) and ((FControlExt as IShellFolder).GetUIObjectOf(FOwner,
  244.       1, pidl, IContextMenu, nil, Pointer(ContextMenu)) = S_OK) then
  245.     begin
  246.       Popup := CreatePopupMenu;
  247.       ContextMenu.QueryContextMenu(Popup, 0, CmdFirst, CmdLast,
  248.         CMF_NORMAL);
  249.       Choice := LoWord(TrackPopupMenu(Popup, TPM_LEFTALIGN or TPM_TOPALIGN or
  250.         TPM_RETURNCMD or TPM_RIGHTBUTTON, Mouse.CursorPos.X, Mouse.CursorPos.Y,
  251.         0, FViewForm.ListView.Handle, nil));
  252.       if Choice <> 0 then
  253.       begin
  254.         FillChar(CmdInfo, SizeOf(CmdInfo), 0);
  255.         with CmdInfo do
  256.         begin
  257.           cbSize := SizeOf(CmdInfo);
  258.           hwnd := FViewForm.ListView.Handle;
  259.           lpVerb := PChar(MakeLong(Choice, 0));
  260.         end;
  261.         ContextMenu.InvokeCommand(CmdInfo);
  262.       end;
  263.     end;
  264.   end;
  265. end;
  266.  
  267. end.
  268.